<!DOCTYPE html>
<html>

<head>
  <title>AddHostObjectToScript Sample</title>
</head>

<body>
  <h1>AddHostObjectToScript Sample</h1>
  <p>The following buttons interact with the <code>chrome.webview.hostObjects.sample</code> object. Open DevTools
    console to try running whatever code you like on this object.</p>
  <h2>Get Property</h2>
  <button id="getPropertyAsyncButton">Get property async</button>
  <label for="getPropertyAsyncButton">Runs <code>await chrome.webview.hostObjects.sample.property</code></label>
  <div><code><pre><span id="getPropertyAsyncOutput"></span></pre></code></div>

  <button id="getPropertySyncButton">Get property sync</button>
  <label for="getPropertySyncButton">Runs <code>chrome.webview.hostObjects.sync.sample.property</code></label>
  <div><code><pre><span id="getPropertySyncOutput"></span></pre></code></div>

  <h2>Set Property</h2>
  <button id="setPropertyAsyncButton">Set property async</button><input type="text" id="setPropertyAsyncInput"
    placeholder="String property value" />
  <label for="setPropertyAsyncButton">Runs <code>chrome.webview.hostObjects.sample.property = value</code> which doesn't
    wait for the property to be set and returns immediately.</label>
  <div><code><pre><span id="setPropertyAsyncOutput"></span></pre></code></div>

  <button id="setPropertyExplicitAsyncButton">Set property explicit async</button><input type="text"
    id="setPropertyExplicitAsyncInput" placeholder="String property value" />
  <label for="setPropertyExplicitAsyncButton">Runs
    <code>await chrome.webview.hostObjects.sample.setHostProperty("property", value)</code> which waits for the property
    to be set.</label>
  <div><code><pre><span id="setPropertyExplicitAsyncOutput"></span></pre></code></div>

  <button id="setPropertySyncButton">Set property sync</button><input type="text" id="setPropertySyncInput"
    placeholder="String property value" />
  <label for="setPropertySyncButton">Runs <code>chrome.webview.hostObjects.sync.sample.property = value</code></label>
  <div><code><pre><span id="setPropertySyncOutput"></span></pre></code></div>

  <h2>Indexed Property</h2>
  <button id="getIndexedPropertyAsyncButton">Get indexed property async</button><input type="text"
    id="getIndexedPropertyAsyncParam" placeholder="Integer index" />
  <label for="getIndexedPropertyAsyncButton">Runs
    <code>await chrome.webview.hostObjects.sample.indexedProperty[paramValue]</code></label>
  <code><pre><span id="getIndexedPropertyAsyncOutput"></span></pre></code>

  <button id="setIndexedPropertyAsyncButton">Set indexed property async</button><input type="text"
    id="setIndexedPropertyAsyncParam1" placeholder="Integer index" /><input type="text"
    id="setIndexedPropertyAsyncParam2" placeholder="String value" />
  <label for="setIndexedPropertyAsyncButton">Runs
    <code>chrome.webview.hostObjects.sync.sample.indexedProperty[paramValue1] = paramValue2</code></label>
  <code><pre><span id="setIndexedPropertyAsyncOutput"></span></pre></code>

  <h2>Invoke Method</h2>
  <button id="invokeMethodAsyncButton">Invoke method async</button><input type="text" id="invokeMethodAsyncParam1"
    placeholder="String parameter" /><input type="text" id="invokeMethodAsyncParam2" placeholder="Integer parameter" />
  <label for="invokeMethodAsyncButton">Runs
    <code>await chrome.webview.hostObjects.sample.MethodWithParametersAndReturnValue(paramValue1, paramValue2)</code></label>
  <code><pre><span id="invokeMethodAsyncOutput"></span></pre></code>

  <button id="invokeMethodSyncButton">Invoke method sync</button><input type="text" id="invokeMethodSyncParam1"
    placeholder="String parameter" /><input type="text" id="invokeMethodSyncParam2" placeholder="Integer parameter" />
  <label for="invokeMethodSyncButton">Runs
    <code>chrome.webview.hostObjects.sync.sample.MethodWithParametersAndReturnValue(paramValue1, paramValue2)</code></label>
  <code><pre><span id="invokeMethodSyncOutput"></span></pre></code>

  <h2>Invoke Callback</h2>
  <button id="invokeCallbackButton">Invoke Callback</button>
  <label for="invokeCallbackButton">Runs
    <code>chrome.webview.hostObjects.sample.CallCallbackAsynchronously(() => { /* ... */ })</code></label>
  <code><pre><span id="invokeCallbackOutput"></span></pre></code>

  <h2>Date Objects</h2>
  <button id="setDateButton">Set Date to Now</button>
  <label for="setDateButton">Sets <code>chrome.webview.hostObjects.options.shouldSerializeDates = true</code> and then
    runs <code>chrome.webview.hostObjects.sample.dateProperty = new Date()</code></label>
  <br />
  <button id="createRemoteDateButton">Set Remote Date</button>
  <label for="createRemoteDateButton">Calls <code>chrome.webview.hostObjects.sample.createNativeDate()</code> to have
    the native object create and set the current time to the DateProperty</label>
  <code><pre><span id="dateOutput"></span></pre></code>

  <div id="worker" style="visibility: hidden">
    <h2>Web Worker</h2>
    <div>Host object on web worker detected.</div>
    <button onclick="toggleSetTimeViaWorker()"> Toggle auto set date via web worker</button>
  </div>

  <div id="div_iframe">
    <h2>IFrame</h2>
  </div>

  <script>
    function enableWebWorker() {
      // The worker can also use the host object if the SDK supports.
      window.worker = new Worker("https://appassets.example/ScenarioAddHostObjectWorker-Staging.js");
      window.setDateViaWorkerEnabled = false;
      worker.onmessage = function (e) {
        // If the worker can detect the host object, it will let the main page know
        // so we can enable the web worker scenario.
        if (e.data === "HostObjectDetected") {
          enableWebWorkerScenario();
        } else if (window.setDateViaWorkerEnabled) {
          // The worker will frequently pass the date it obtained from the host object.
          document.getElementById("dateOutput").textContent = "sample.dateProperty via worker: " + e.data;
        }
      };
    }

    function enableWebWorkerScenario() {
      document.getElementById("worker").style.visibility = "visible";
    }

    function toggleSetTimeViaWorker() {
      window.setDateViaWorkerEnabled = !window.setDateViaWorkerEnabled;
      if (window.setDateViaWorkerEnabled) {
        window.worker.postMessage("enable");
      } else {
        window.worker.postMessage("disable");
      }
    }

    //! Create IFrame from the parent html page and load it
    function createIFrame() {
      var i = document.createElement("iframe");
      i.src = "https://appassets.example/ScenarioAddHostObject.html";
      i.scrolling = "auto";
      i.frameborder = "0";
      i.height = "90%";
      i.width = "100%";
      i.name = "iframe_name";
      var div = document.getElementById("div_iframe");
      div.appendChild(i); div.style.display = 'block';
    };

    window.onload = function () {
      if (window.top === window) {
        createIFrame();
      }
    };

    //! [HostObjectUsage]
    document.getElementById("getPropertyAsyncButton").addEventListener("click", async () => {
      const propertyValue = await chrome.webview.hostObjects.sample.property;
      document.getElementById("getPropertyAsyncOutput").textContent = propertyValue;
    });

    document.getElementById("getPropertySyncButton").addEventListener("click", () => {
      const propertyValue = chrome.webview.hostObjects.sync.sample.property;
      document.getElementById("getPropertySyncOutput").textContent = propertyValue;
    });

    document.getElementById("setPropertyAsyncButton").addEventListener("click", async () => {
      const propertyValue = document.getElementById("setPropertyAsyncInput").value;
      // The following line will work but it will return immediately before the property value has actually been set.
      // If you need to set the property and wait for the property to change value, use the setHostProperty function.
      chrome.webview.hostObjects.sample.property = propertyValue;
      document.getElementById("setPropertyAsyncOutput").textContent = "Set";
    });

    document.getElementById("setPropertyExplicitAsyncButton").addEventListener("click", async () => {
      const propertyValue = document.getElementById("setPropertyExplicitAsyncInput").value;
      // If you care about waiting until the property has actually changed value use the setHostProperty function.
      await chrome.webview.hostObjects.sample.setHostProperty("property", propertyValue);
      document.getElementById("setPropertyExplicitAsyncOutput").textContent = "Set";
    });

    document.getElementById("setPropertySyncButton").addEventListener("click", () => {
      const propertyValue = document.getElementById("setPropertySyncInput").value;
      chrome.webview.hostObjects.sync.sample.property = propertyValue;
      document.getElementById("setPropertySyncOutput").textContent = "Set";
    });

    document.getElementById("getIndexedPropertyAsyncButton").addEventListener("click", async () => {
      const index = parseInt(document.getElementById("getIndexedPropertyAsyncParam").value);
      const resultValue = await chrome.webview.hostObjects.sample.IndexedProperty[index];
      document.getElementById("getIndexedPropertyAsyncOutput").textContent = resultValue;
    });
    document.getElementById("setIndexedPropertyAsyncButton").addEventListener("click", async () => {
      const index = parseInt(document.getElementById("setIndexedPropertyAsyncParam1").value);
      const value = document.getElementById("setIndexedPropertyAsyncParam2").value;;
      chrome.webview.hostObjects.sample.IndexedProperty[index] = value;
      document.getElementById("setIndexedPropertyAsyncOutput").textContent = "Set";
    });
    document.getElementById("invokeMethodAsyncButton").addEventListener("click", async () => {
      const paramValue1 = document.getElementById("invokeMethodAsyncParam1").value;
      const paramValue2 = parseInt(document.getElementById("invokeMethodAsyncParam2").value);
      const resultValue = await chrome.webview.hostObjects.sample.MethodWithParametersAndReturnValue(paramValue1, paramValue2);
      document.getElementById("invokeMethodAsyncOutput").textContent = resultValue;
    });

    document.getElementById("invokeMethodSyncButton").addEventListener("click", () => {
      const paramValue1 = document.getElementById("invokeMethodSyncParam1").value;
      const paramValue2 = parseInt(document.getElementById("invokeMethodSyncParam2").value);
      const resultValue = chrome.webview.hostObjects.sync.sample.MethodWithParametersAndReturnValue(paramValue1, paramValue2);
      document.getElementById("invokeMethodSyncOutput").textContent = resultValue;
    });

    let callbackCount = 0;
    document.getElementById("invokeCallbackButton").addEventListener("click", async () => {
      chrome.webview.hostObjects.sample.CallCallbackAsynchronously(() => {
        document.getElementById("invokeCallbackOutput").textContent = "Native object called the callback " + (++callbackCount) + " time(s).";
      });
    });

    // Date property
    document.getElementById("setDateButton").addEventListener("click", () => {
      chrome.webview.hostObjects.options.shouldSerializeDates = true;
      chrome.webview.hostObjects.sync.sample.dateProperty = new Date();
      document.getElementById("dateOutput").textContent = "sample.dateProperty: " + chrome.webview.hostObjects.sync.sample.dateProperty;
    });
    document.getElementById("createRemoteDateButton").addEventListener("click", () => {
      chrome.webview.hostObjects.sync.sample.createNativeDate();
      document.getElementById("dateOutput").textContent = "sample.dateProperty: " + chrome.webview.hostObjects.sync.sample.dateProperty;
    });

    //! [HostObjectUsage]
  </script>
</body>

</html>